package com.kabigon.tiny.service;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

public class ExcelExportTool {
    public static void export(List<List<String>> data, ExcelExportConfig config, String filePath) {
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet(config.getSheetName());

        int rowIndex = 0;
        for (List<String> rowData : data) {
            Row row = sheet.createRow(rowIndex);
            int columnIndex = 0;
            for (String cellData : rowData) {
                Cell cell = row.createCell(columnIndex);
                cell.setCellValue(cellData);
                columnIndex++;
            }
            rowIndex++;
        }

        if (config.isMergeRows()) {
            mergeRows(sheet, config.getStartRow(), config.getEndRow(), config.getStartColumn(), config.getEndColumn());
        }

        if (config.isMergeColumns()) {
            mergeColumns(sheet, config.getStartRow(), config.getEndRow(), config.getStartColumn(), config.getEndColumn());
        }

        if (config.getRowSpan() > 1 || config.getColumnSpan() > 1) {
            mergeRowsAndColumns(sheet, config.getStartRow(), config.getRowSpan(), config.getStartColumn(), config.getColumnSpan());
        }

        if (config.isCenterFirstRow()) {
            centerRow(sheet, config.getStartRow());
        }

        try (FileOutputStream fileOut = new FileOutputStream(filePath)) {
            workbook.write(fileOut);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static void mergeRowsAndColumns(Sheet sheet, int startRow, int rowSpan, int startColumn, int columnSpan) {
        int endRow = startRow + rowSpan - 1;
        int endColumn = startColumn + columnSpan - 1;
        sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, startColumn, endColumn));
    }

    private static void mergeRows(Sheet sheet, int startRow, int endRow, int startColumn, int endColumn) {
        for (int i = startRow; i <= endRow; i++) {
            sheet.addMergedRegion(new CellRangeAddress(i, i, startColumn, endColumn));
        }
    }

    private static void mergeColumns(Sheet sheet, int startRow, int endRow, int startColumn, int endColumn) {
        for (int i = startColumn; i <= endColumn; i++) {
            sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, i, i));
        }
    }

    private static void centerRow(Sheet sheet, int rowIndex) {
        Row row = sheet.getRow(rowIndex);
        if (row != null) {
            CellStyle style = sheet.getWorkbook().createCellStyle();
            style.setAlignment(HorizontalAlignment.CENTER);
            for (Cell cell : row) {
                cell.setCellStyle(style);
            }
        }
    }
}
